using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Web;
using System.Net.Mail;
using System.Web.Services;
using System.Collections;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
using newtelligence.DasBlog.Runtime;
using newtelligence.DasBlog.Web.Core;
using dasBlog.Services.Contracts.Rsd;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.Web.Security;

namespace newtelligence.DasBlog.Web.Services
{
	/// <summary>
	/// Summary description for DasBlogEditting.
	/// </summary>
    [ServiceBehavior(ConfigurationName="EditService")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class EditService : IEditService
	{
		
		public bool CanEdit(string username, string password)
		{
			if (!SiteConfig.GetSiteConfig().EnableEditService)
			{
				throw new ServiceDisabledException();
			}

			try
			{
				if (HttpContext.Current.Request.IsAuthenticated)
				{
					return (Roles.IsUserInRole("admin")||Roles.IsUserInRole("contributor"));
				}
                else if (Membership.ValidateUser(username, password))
                {
                    return Roles.IsUserInRole(username, "admin") ||
                           Roles.IsUserInRole(username, "contributor");
                }
                else
                {
                    return false;
                }
			}
			catch (Exception e)
			{
				ErrorTrace.Trace(TraceLevel.Error, e);
				return false;
			}
		}

		
		private RsdRoot GetRsd()
		{
            // TODO: NLS - Make the default API configurable through SiteConfig
			SiteConfig siteConfig = SiteConfig.GetSiteConfig();
			RsdApiCollection apiCollection = new RsdApiCollection();

			RsdRoot rsd = new RsdRoot();
			RsdService dasBloggingService = new RsdService();
			dasBloggingService.HomePageLink = Utils.GetBaseUrl(siteConfig);

			RsdApi metaWeblog    = new RsdApi();
			metaWeblog.Name      = "MetaWeblog";
			metaWeblog.Preferred = ( siteConfig.PreferredBloggingAPI == metaWeblog.Name );
			metaWeblog.ApiLink   = Utils.GetBloggerUrl(siteConfig);
			metaWeblog.BlogID    = dasBloggingService.HomePageLink;
			apiCollection.Add(metaWeblog);

			RsdApi blogger    = new RsdApi();
			blogger.Name      = "Blogger";
			blogger.Preferred = ( siteConfig.PreferredBloggingAPI == blogger.Name );
			blogger.ApiLink   = Utils.GetBloggerUrl(siteConfig);
			blogger.BlogID    = dasBloggingService.HomePageLink;
			apiCollection.Add(blogger);

            RsdApi moveableType    = new RsdApi();
            moveableType.Name      = "Moveable Type";
            moveableType.Preferred = ( siteConfig.PreferredBloggingAPI == moveableType.Name );
            moveableType.ApiLink   = Utils.GetBloggerUrl( siteConfig );
            moveableType.BlogID    = dasBloggingService.HomePageLink;
            apiCollection.Add( moveableType );

			dasBloggingService.RsdApiCollection = apiCollection;
			rsd.Services.Add(dasBloggingService);

			return rsd;
		}

		public void DeleteEntry(string entryId, string username, string password)
		{
			SiteConfig siteConfig = SiteConfig.GetSiteConfig();
			if (!siteConfig.EnableEditService)
			{
				throw new ServiceDisabledException();
			}

			if (!Membership.ValidateUser(username, password) || !Roles.IsUserInRole(username,"admin"))
			{
				throw new Exception("Invalid Password");
			}

			ILoggingDataService loggingService = LoggingDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.LogDir));
            IBlogDataService dataService = BlogDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.ContentDir), System.Web.Hosting.HostingEnvironment.MapPath(SiteConfig.GetSiteConfig().BinariesDir), loggingService);

			//dataService.DeleteEntry(entryId, siteConfig.CrosspostSites);
            Utils.DeleteEntry(entryId, siteConfig, loggingService, dataService);
		}

        private string UpdateEntry(Entry entry, string username, string password)
		{
			SiteConfig siteConfig = SiteConfig.GetSiteConfig();
			if (!siteConfig.EnableEditService)
			{
				throw new ServiceDisabledException();
			}

            if (!Membership.ValidateUser(username, password) || !Roles.IsUserInRole(username, "admin"))
			{
				throw new Exception("Invalid Password");
			}

			ILoggingDataService loggingService = LoggingDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.LogDir));
            IBlogDataService dataService = BlogDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.ContentDir), System.Web.Hosting.HostingEnvironment.MapPath(SiteConfig.GetSiteConfig().BinariesDir), loggingService);

            EntrySaveState val = Utils.UpdateEntry(entry, null, null, siteConfig, loggingService, dataService);

            string rtn = string.Empty;
            if (val.Equals(EntrySaveState.Updated))
                rtn = entry.EntryId;
            else
                rtn = val.ToString();

            return rtn;
		}

        private string CreateEntry(Entry entry, string username, string password)
		{
			SiteConfig siteConfig = SiteConfig.GetSiteConfig();
			if (!siteConfig.EnableEditService)
			{
				throw new ServiceDisabledException();
			}

            if (!Membership.ValidateUser(username, password) || !Roles.IsUserInRole(username, "admin"))
			{
				throw new Exception("Invalid Password");
			}

			// ensure that the entryId was filled in
			//
			if (entry.EntryId == null || entry.EntryId.Length == 0)
			{
				entry.EntryId = Guid.NewGuid().ToString();
			}

			// ensure the dates were filled in, otherwise use NOW
			if (entry.CreatedUtc == DateTime.MinValue)
			{
				entry.CreatedUtc = DateTime.UtcNow;
			}
			if (entry.ModifiedUtc == DateTime.MinValue)
			{
				entry.ModifiedUtc = DateTime.UtcNow;
			}

			ILoggingDataService loggingService = LoggingDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.LogDir));
            IBlogDataService dataService = BlogDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.ContentDir), System.Web.Hosting.HostingEnvironment.MapPath(SiteConfig.GetSiteConfig().BinariesDir), loggingService);

            Utils.SaveEntry(entry, string.Empty, null, siteConfig, loggingService, dataService);

			return entry.EntryId;
		}
        
        /// <summary>
        /// 12 Oct 2006 / MOT :
        /// Get entry by date and title.  If there is more than one match, the most recent entry will be returned.
        /// </summary>
        /// <param name="entryDate">Date the entry was posted.</param>
        /// <param name="entryTitle">Title of the post.</param>
        /// <returns>DasBlog.Runtime.Entry</returns>
        private Entry GetEntry(DateTime entryDate, string entryTitle)
        {
            SiteConfig siteConfig = SiteConfig.GetSiteConfig();
            ILoggingDataService loggingService = LoggingDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.LogDir));
            IBlogDataService dataService = BlogDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.ContentDir), System.Web.Hosting.HostingEnvironment.MapPath(SiteConfig.GetSiteConfig().BinariesDir), loggingService);

            //Only pass in the date portion of the entry date, do not pass in the time portion.
            DayEntry dayEntry = dataService.GetDayEntry(entryDate.Date);

            //this replacement of characters in the title was lifted directly from
            //  DasBlog.Web.Core::TitleMapperModule.HandleBeginRequest()
            entryTitle = entryTitle.Replace(".aspx", "");
            entryTitle = entryTitle.Replace("+", "");
            entryTitle = entryTitle.Replace(" ", "");
            entryTitle = entryTitle.Replace("%2b", "");
            entryTitle = entryTitle.Replace("%20", "");

            //now that we have a properly formatted title, use it to get a specific
            //  entry from the DayEntry object.  If there is more than one match to the
            //  title, the most recent entry will be matched.
            Entry entry = dayEntry.GetEntryByTitle(entryTitle);

            return entry;
        }
        /// <summary>
        /// 12 Oct 2006 / MOT :
        /// Get entry by unique guid string.  This will return, at most, one entry.
        /// </summary>
        /// <param name="entryId">guid string</param>
        /// <returns>DasBlog.Runtime.Entry</returns>
        private Entry GetEntry(string entryId)
        {
            SiteConfig siteConfig = SiteConfig.GetSiteConfig();
            ILoggingDataService loggingService = LoggingDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.LogDir));
            IBlogDataService dataService = BlogDataServiceFactory.GetService(System.Web.Hosting.HostingEnvironment.MapPath(siteConfig.ContentDir), System.Web.Hosting.HostingEnvironment.MapPath(SiteConfig.GetSiteConfig().BinariesDir), loggingService);

            Entry entry = dataService.GetEntry(entryId);
            return entry;
        }

        public GetRsdResponse GetRsd(GetRsdRequest request)
        {
            return new GetRsdResponse(GetRsd());
        }

        public UpdateEntryResponse UpdateEntry(UpdateEntryRequest request)
        {
            return new UpdateEntryResponse(UpdateEntry(request.entry, request.username, request.password));
        }

        public CreateEntryResponse CreateEntry(CreateEntryRequest request)
        {
            return new CreateEntryResponse(CreateEntry(request.entry, request.username, request.password));

        }

        public GetEntryByDateAndTitle1 GetEntry(GetEntryByDateAndTitle request)
        {
            return new GetEntryByDateAndTitle1(GetEntry(request.entryDate, request.entryTitle)); 
        }

        public GetEntryByEntryID1 GetEntry1(GetEntryByEntryID request)
        {
            return new GetEntryByEntryID1(GetEntry(request.entryId));
        }

        
    }
}
